package com.pricl.frame.common.utils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

public class NumberUtils {

	public static Integer formatInt(Float num) {
		return Math.round(num.floatValue());
	}

	public static BigDecimal format(BigDecimal num) {
		return format(num, 2);
	}

	public static BigDecimal format(BigDecimal num, int scale) {
		if (num == null) {
			return null;
		}
		if (scale < 0) {
			scale = 0;
		}
		return num.setScale(scale, BigDecimal.ROUND_HALF_UP);
	}

	public static Double format(double num) {
		return format(new Double(num));
	}

	public static Double format(double num, int scale) {
		return format(new Double(num), scale);
	}

	public static Double format(Double num) {
		return format(num, 2);
	}

	public static Double format(Double num, int scale) {
		if (num == null) {
			return null;
		}
		return new BigDecimal(num.doubleValue()).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	public static Integer formatDouToInt(Double num, int scale) {
		if (num == null) {
			return null;
		}
		return new BigDecimal(num.doubleValue()).setScale(scale, BigDecimal.ROUND_HALF_UP).intValue();
	}

	public static Long formatDouToLong(Double num, int scale) {
		if (num == null) {
			return null;
		}
		return new BigDecimal(num.doubleValue()).setScale(scale, BigDecimal.ROUND_HALF_UP).longValue();
	}

	public static Float format(Float num, int scale) {
		if (num == null) {
			return null;
		}
		return new BigDecimal(num.doubleValue()).setScale(scale, BigDecimal.ROUND_HALF_UP).floatValue();
	}

	public static int sum(Integer... values) {
		if (values == null || values.length == 0) {
			return 0;
		}
		int sum = 0;
		for (Integer value : values) {
			if (value != null) {
				sum += value;
			}
		}
		return sum;
	}

	public static long sum(Long... values) {
		if (values == null || values.length == 0) {
			return 0;
		}
		long sum = 0;
		for (Long value : values) {
			if (value != null) {
				sum += value;
			}
		}
		return sum;
	}

	public static double sum(Double... values) {
		if (values == null || values.length == 0) {
			return 0.0;
		}
		double sum = 0.0;
		for (Double value : values) {
			if (value != null) {
				sum += value;
			}
		}
		return sum;
	}

	public static double avg(Double... values) {
		if (values == null || values.length == 0) {
			return 0.0;
		}
		double sum = 0.0;
		for (Double value : values) {
			if (value != null) {
				sum += value;
			}
		}
		return sum / values.length;
	}

	public static double avgNotNull(Double... values) {
		if (values == null || values.length == 0) {
			return 0.0;
		}
		double sum = 0.0;
		int length = 0;
		for (Double value : values) {
			if (value != null) {
				sum += value;
				length++;
			}
		}
		if (length == 0) {
			return 0.0;
		}
		return sum / length;
	}

	public static double avgNotZero(Double... values) {
		if (values == null || values.length == 0) {
			return 0.0;
		}
		double sum = 0.0;
		int length = 0;
		for (Double value : values) {
			if (value != null && value != 0) {
				sum += value;
				length++;
			}
		}
		if (length == 0) {
			return 0.0;
		}
		return sum / length;
	}

	public static Double parseDouble(Object number) {
		if (number == null) {
			return null;
		}
		if (number instanceof String) {
			try {
				number = Double.valueOf((String) number);
			} catch (NumberFormatException e) {
			}
		}
		if (!(number instanceof Number)) {
			return null;
		}
		return ((Number) number).doubleValue();
	}

	public static int parseInt(String value) {
		if (value == null) {
			return 0;
		}
		value = value.replaceAll("^(\\D|0)+", "");
		try {
			return Integer.parseInt(value);
		} catch (NumberFormatException e) {
			return 0;
		}
	}

	public static Float parsePercent(String percent) {
		if (percent == null || percent.indexOf('%') == -1) {
			return null;
		}
		try {
			return Float.valueOf(percent.replace("%", ""));
		} catch (NumberFormatException e) {
		}
		return null;
	}

	public static int[] parseInt(String value, String serp) {
		if (value == null || serp == null || serp.isEmpty())
			return null;
		String[] values = value.split(serp);
		List<Integer> ints = new ArrayList<Integer>();
		for (String val : values) {
			try {
				ints.add(Integer.valueOf(val));
			} catch (NumberFormatException e) {
			}
		}
		int[] is = new int[ints.size()];
		int index = 0;
		for (Integer i : ints) {
			is[index++] = i;
		}
		return is;
	}

	public static List<Integer> parseInt(String value, String serp, String fromto) {
		List<Integer> ints = new ArrayList<Integer>();
		String[] props = value.split(serp);
		for (String prop : props) {
			try {
				ints.add(Integer.valueOf(prop.trim()));
			} catch (NumberFormatException e) {
				String[] vals = prop.split(fromto);
				if (vals.length != 2) {
					try {
						int start = Integer.parseInt(vals[0].trim());
						int end = Integer.parseInt(vals[1].trim());
						for (int i = start; i <= end; i++) {
							ints.add(i);
						}
					} catch (NumberFormatException e1) {
					}
				}
			}
		}
		return ints;
	}

	public static int[] fetchRandom(int begin, int end, int count) {
		int len = end - begin;
		if (len <= 0) {
			return new int[] { begin };
		}
		int index = 0;
		if (len < count) {
			int[] ints = new int[len + 1];
			index = 0;
			for (int i = begin; i <= end; i++) {
				ints[index++] = i;
			}
			return ints;
		}
		Random random = new Random();
		int[] rints = new int[count];
		for (int i = 0; i < count; i++) {
			rints[i] = random.nextInt(len);
		}
		Arrays.sort(rints);
		int curr = rints[0];
		for (int i = 1; i < count; i++) {
			if (curr >= rints[i]) {
				curr = rints[i] = curr < end ? curr + 1 : curr;
			} else {
				curr = rints[i];
			}
		}
		curr = rints[count - 1];
		for (int i = count - 2; i >= 0; i--) {
			if (curr <= rints[i]) {
				curr = rints[i] = curr > 0 ? curr - 1 : 0;
			} else {
				curr = rints[i];
			}
		}
		return rints;
	}

	public static int orValue(int[] values) {
		if (values == null || values.length == 0) {
			return 0;
		}
		int value = 0;
		for (int val : values) {
			value |= val;
		}
		return value;
	}
}
